package allen.js;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;

public class JsTest {
	public static void main(String[] args) throws Exception {
		test04();
	}

	private static void test01() {
		StringBuilder sb = new StringBuilder();
		sb.append("(").append("\n");
		sb.append("function foo(param) {").append("\n");
		sb.append(" console.log('[JS] Hello!' + param + '!');").append("\n");
		sb.append(" return param.toUpperCase();").append("\n");
		sb.append("}").append("\n");
		sb.append(")");

		try (Context context = Context.newBuilder("js").option("js.ecmascript-version", "2020").build()) {
			Value jsFunction = context.eval("js", sb.toString());

			Value result = jsFunction.execute("allen");

			System.out.println("[JAVA]: " + result.asString());
		}
	}

	private static void test02() {
		StringBuilder sb = new StringBuilder();
		sb.append("function foo(param) {").append("\n");
		sb.append(" console.log('[JS] Hello!' + param + '!');").append("\n");
		sb.append(" return param.toUpperCase();").append("\n");
		sb.append("}").append("\n");
		sb.append("function cal(r){").append("\n");
		sb.append(" let aa=10;").append("\n");
		sb.append(" console.log(foo('abc'));").append("\n");
		sb.append(" return Math.PI*r*r;").append("\n");
		sb.append("}").append("\n");

		try (Context context = Context.newBuilder("js").option("js.ecmascript-version", "2020").build()) {
			context.eval("js", sb.toString());

			Value cal = context.getBindings("js").getMember("cal");

			Value result = cal.execute(2);

			System.out.println("[JAVA Area]: " + result.asDouble());
		}
	}

	private static void test03() throws ScriptException, NoSuchMethodException {
		StringBuilder sb = new StringBuilder();
		sb.append("function foo(param) {").append("\n");
		sb.append(" console.log('[JS] Hello!' + param + '!');").append("\n");
		sb.append(" return param.toUpperCase();").append("\n");
		sb.append("}").append("\n");
		sb.append("function cal(r){").append("\n");
		sb.append(" let aa=10;").append("\n");
		sb.append(" console.log(foo('abc'));").append("\n");
		sb.append(" return Math.PI*r*r;").append("\n");
		sb.append("}").append("\n");

		ScriptEngine script = new ScriptEngineManager().getEngineByName("graal.js");

		script.eval(sb.toString());
		Invocable inv = (Invocable) script;
		Object result = inv.invokeFunction("cal", 2);

		System.out.println("[JAVA Area]: " + result.toString());
	}

	private static void test04() {
		String firseStr = "a*3";
		String secondStr = "Math.PI*a*a";

		try (Context context = Context.newBuilder("js").option("js.ecmascript-version", "2020").build()) {
			context.eval("js", "let a=12.3");

			double result1 = context.eval("js", firseStr).asDouble();
			double result2 = context.eval("js", secondStr).asDouble();

			System.out.println("[JAVA Area]: " + result1);
			System.out.println("[JAVA Area]: " + result2);
		}
	}

	private static void test05() throws ScriptException {
		String firseStr = "a*3";
		String secondStr = "Math.PI*a*a";

		ScriptEngine script = new ScriptEngineManager().getEngineByName("graal.js");
		script.put("a", 12.3);

		Object result1 = script.eval(firseStr);
		Object result2 = script.eval(secondStr);

		System.out.println("[JAVA Area]: " + result1.toString());
		System.out.println("[JAVA Area]: " + result2.toString());
	}

}
